﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace t_205_verk_hopur_12.Models
{
    public class ScheduleRepository : t_205_verk_hopur_12.Models.IScheduleRepository
    {
        private MittTVDataContext db = new MittTVDataContext();

        // Returns a single video based on the schedule id
        public ScheduleVideo getScheduleById(int scheduleID)
        {
            return (from schedule in db.Schedules
                    where schedule.ID == scheduleID
                    join video in db.Videos on schedule.VideoID equals video.ID into sb
                    select new ScheduleVideo
                    {
                        ID = schedule.ID,
                        ChannelID = schedule.ChannelID,
                        VideoID = schedule.VideoID,
                        StartTime = schedule.StartTime,
                        EndTime = schedule.EndTime,
                        UserID = schedule.Video.UserID,
                        Title = schedule.Video.Title,
                        Description = schedule.Video.Description,
                        Rating = schedule.Video.Rating,
                        Embed = schedule.Video.Embed
                    }).SingleOrDefault();
        }

        // Returns the current video being played in the channel
        public ScheduleVideo GetCurrentScheduleVideoByID(int channelID)
        {
            int noVideosToday = GetScheduleByDay(channelID, DateTime.Now).Count();

            // If there are no videos today, we return null
            if (noVideosToday > 0)
            {
                // Fetches all of the videos scheduled today, so we can narrow the search further down
                var today = from schedule in db.Schedules
                            join video in db.Videos on schedule.VideoID equals video.ID into sb
                            where schedule.ChannelID == channelID
                            && schedule.StartTime.Year == DateTime.Now.Year
                            && schedule.StartTime.Month == DateTime.Now.Month
                            && schedule.StartTime.Day == DateTime.Now.Day
                            select new ScheduleVideo
                            {
                                ID = schedule.ID,
                                ChannelID = schedule.ChannelID,
                                VideoID = schedule.VideoID,
                                StartTime = schedule.StartTime,
                                EndTime = schedule.EndTime,
                                UserID = schedule.Video.UserID,
                                Title = schedule.Video.Title,
                                Description = schedule.Video.Description,
                                Rating = schedule.Video.Rating,
                                Embed = schedule.Video.Embed
                            };

                // Fetches the video that should be currently playing today
                var normalSchedule = (from schedule in today
                                        where schedule.StartTime <= DateTime.Now
                                        orderby schedule.StartTime descending
                                        select schedule).FirstOrDefault();

                // If we get something from that, then we return it
                if (normalSchedule != null)
                {
                    return normalSchedule;
                }

                // Else we get the first video of the day, this means that the schedule has not started
                return (from schedule in today
                        where schedule.StartTime >= DateTime.Now
                        select schedule).FirstOrDefault();
            }

            return null;
        }

        // To get videos from a particular day
        public IQueryable<ScheduleVideo> GetScheduleByDay(int channelID, DateTime date)
        {
            return from schedule in db.Schedules
                   join video in db.Videos on schedule.VideoID equals video.ID into sb
                   where schedule.ChannelID == channelID &&
                         schedule.StartTime.DayOfYear == date.DayOfYear && 
                         schedule.StartTime.Year == date.Year
                   orderby schedule.StartTime
                   select new ScheduleVideo
                   {
                       ID = schedule.ID,
                       ChannelID = schedule.ChannelID,
                       VideoID = schedule.VideoID,
                       StartTime = schedule.StartTime,
                       EndTime = schedule.EndTime,
                       UserID = schedule.Video.UserID,
                       Title = schedule.Video.Title,
                       Description = schedule.Video.Description,
                       Rating = schedule.Video.Rating,
                       Embed = schedule.Video.Embed
                   };
        }

        // Adds a new schedule based on the parameters
        public void AddToSchedule(int id, int videoID, DateTime startTime, DateTime endTime)
        {
            Schedule newSchedule = new Schedule { ChannelID = id, 
                                                  VideoID = videoID, 
                                                  StartTime = startTime, 
                                                  EndTime = endTime };

            db.Schedules.InsertOnSubmit(newSchedule);
            db.SubmitChanges();
        }

        // Saving changes to database, Persistence
        public void Save()
        {
            db.SubmitChanges();
        }

        // Gets a single schedule item
        public Schedule getScheduleItemById(int scheduleID)
        {
            return (from schedule in db.Schedules
                    where schedule.ID == scheduleID
                    select schedule).FirstOrDefault();
        }

        // Returns true if there is an overlap in the proposed start and end times 
        // for a new schedule within the channel
        public bool CheckForOverlapInSchedule(int channelID, int scheduleID, DateTime startTime, DateTime endTime)
        {
            return (from schedule in db.Schedules
                    where schedule.ChannelID == channelID &&
                    (
                        (
                            (schedule.StartTime >= startTime && schedule.StartTime <= endTime) ||
                            (schedule.EndTime >= startTime && schedule.EndTime <= endTime)
                        ) && schedule.ID != scheduleID
                    )
                    select schedule).Count() >= 1;
        }

        // Deletes the schedule by ID
        public void DeleteSchedule(int scheduleID)
        {
            db.Schedules.DeleteOnSubmit(getScheduleItemById(scheduleID));
            db.SubmitChanges();
        }
    }
}
